﻿//Javascript Libary for the mvi_searchui.html


function openSelectedPerson(obj) {

    showExecutingSearch();

    var filter = "$select=*&$filter=";
    filter += buildQueryFilter("crme_Alias", obj.getAttribute("crme_Alias"), false);
    filter += buildQueryFilter("crme_DeceasedDate", obj.getAttribute("crme_DeceasedDate"), true);
    filter += buildQueryFilter("crme_DOBString", obj.getAttribute("crme_DOBString"), true);
    filter += buildQueryFilter("crme_EDIPI", obj.getAttribute("crme_EDIPI"), true);
    filter += buildQueryFilter("crme_Gender", obj.getAttribute("crme_Gender"), true);
    filter += buildQueryFilter("crme_IdentityTheft", obj.getAttribute("crme_IdentityTheft"), true);
    filter += buildQueryFilter("crme_PrimaryPhone", obj.getAttribute("crme_PrimaryPhone"), true);
    filter += buildQueryFilter("crme_RecordSource", obj.getAttribute("crme_RecordSource"), true);
    filter += buildQueryFilter("crme_SSN", obj.getAttribute("crme_SSN"), true);
    filter += buildQueryFilter("crme_FullAddress", obj.getAttribute("crme_FullAddress"), true);
    filter += buildQueryFilter("crme_FullName", obj.getAttribute("crme_FullName"), true);
    filter += buildQueryFilter("crme_PatientMviIdentifier", obj.getAttribute("crme_PatientMviIdentifier"), true);
    filter += buildQueryFilter("crme_SearchType", 'SelectedPersonSearch', true);
    filter += buildQueryFilter("crme_ClassCode", obj.getAttribute("crme_ClassCode"), true);
    filter += buildQueryFilter("crme_ReturnMessage", obj.getAttribute("crme_ReturnMessage"), true);
    filter += buildQueryFilter("crme_url", SERVER_URL, true);

    try {
        SDK.REST.retrieveMultipleRecords("crme_person", filter, selectedPersonCallBack, searchErrorCallback, enableButtons);
    }
    catch (e) {
        searchErrorCallback(e);
    }

    return false;
}

function searchSucessCallback(data, textStatus, XmlHttpRequest) {
    hideAll();

    var table = $("#personSearchResultsTable");
    $("#personSearchResultsTable").find("thead, tr, th").remove();
    $("#personSearchResultsTable").find("tr:gt(0)").remove();

    if (data != null && data.length > 0) {

        //if only 1 item is returned, check to see if an error response was returned from MVI
        //if so, exit the callback
        if (data.length == 1 && !evaluateMviMessage(data[0]))
            return;

        $("#searchResultsGrid").show();

        var headers = ['Name', 'Alias', 'Gender', 'Date of Birth', 'SSN', 'EDIPI', 'Address', 'Phone', 'Deceased Date', 'Identity Theft', 'Source'];
        var thead = document.createElement('tr');

        for (var i = 0; i < headers.length; i++) {
            var th = document.createElement('th');
            th.className = "grid_title";
            th.appendChild(document.createTextNode(headers[i]));
            th.id = "th_" + headers[i].replace(' ', '');
            th.title = headers[i];
            th.scope = "col";
            thead.appendChild(th);
        }

        table.append(thead);

        for (var i = 0; i < data.length; i++) {
            var row = document.createElement('tr');
            
            var crmValues = getCrmValues(data[i], row);
            for (var j = 0; j < headers.length; j++) {
                if (j == 0) {
                    var td = document.createElement('th');
                    td.scope = "row";
                }
                else {
                    var td = document.createElement('td');                    
                }

                td.id = "th_" + i + "_" + j + "_" + headers[j].replace(' ', '');
                td.title = crmValues[j];

                td.appendChild(document.createTextNode(crmValues[j]));
                row.appendChild(td);
            }
            row.className = "grid_row";
            row.ondblclick = function () { openSelectedPerson(this); };
            table.append(row);
        }

        //Force focus to message
        table.focus();
    }
    else {
        enableButtons();
        $("#warningDetails").text("");
        $("#warningDetails").append("No matches where returned from MVI matching the data provided. Please refine your search and try again.");
        $("#msgBoxNoDataReturned").show();

        //Force focus to message
        $("#msgBoxNoDataReturned").focus();
    }
}

function selectedPersonCallBack(data) {
    hideAll();
    enableButtons();

    if (data != null) {
        if (evaluateMviMessage(data[0])) {
            if (parent.Xrm.Page.data != null &&
                parent.Xrm.Page.data.entity != null &&
                parent.Xrm.Page.data.entity.getEntityName() == "serviceappointment") {
                var contactObj = { id: data[0].crme_ContactId, name: data[0].crme_FullName };
                var newContactRef =
                {
                    id: '{' + contactObj.id + '}',
                    name: contactObj.name,
                    entityType: "contact"
                };
                var existingContacts = parent.Xrm.Page.getAttribute("customers");
                var contactList = existingContacts.getValue();
                if (contactList != null)
                    contactList.push(newContactRef);
                else
                    contactList = [newContactRef];
                existingContacts.setValue(contactList);
                existingContacts.setSubmitMode("always");
            }
            else if (parent.Xrm.Page.data != null &&
            parent.Xrm.Page.data.entity != null &&
            parent.Xrm.Page.data.entity.getEntityName() == "appointment") {
                var contactObj = { id: data[0].crme_ContactId, name: data[0].crme_FullName };
                var participants = new Array();
                participants[0] = new Object();
                participants[0].id = contactObj.id;
                participants[0].name = contactObj.name;
                participants[0].entityType = "contact";

                var veteranAttribute = parent.Xrm.Page.getAttribute("optionalattendees");
                if (veteranAttribute != null) {
                    var veterans = veteranAttribute.getValue();
                    if (veterans != null) {
                        for (var i = 1; i <= veterans.length; i++) {
                            participants[i] = new Object();
                            //Populate optional attendees field
                            participants[i].id = veterans[i - 1].id;
                            participants[i].name = veterans[i - 1].name;
                            participants[i].entityType = "contact";
                        }
                    }
                    veteranAttribute.setValue(participants);
                    parent.MCS.Patients = participants;
                }
                else {
                    alert("Veterans field not available.");
                }
            }
            else {
                var url = data[0].crme_url;
                window.open(url);
            }
        }
    }
    else {
        //fn already called earlier
        //enableButtons();
        $("#warningDetails").text("");
        $("#warningDetails").append("No data was returned for the selected person. Please try again.");
        $("#msgBoxNoDataReturned").show();
    }
}

function getCrmValues(data, row) {
    //get the display values
    var alias = data.crme_Alias == null ? "" : data.crme_Alias;
    row.setAttribute("crme_Alias", alias);

    var deceasedDate = data.crme_DeceasedDate == null ? "" : data.crme_DeceasedDate;
    row.setAttribute("crme_DeceasedDate", deceasedDate);

    var dateOfBirth = data.crme_DOBString == null ? "" : data.crme_DOBString;
    row.setAttribute("crme_DOBString", dateOfBirth);

    var edipi = data.crme_EDIPI == null ? "" : data.crme_EDIPI;
    row.setAttribute("crme_EDIPI", edipi);

    var gender = data.crme_Gender == null ? "" : data.crme_Gender;
    row.setAttribute("crme_Gender", gender);

    var identityTheft = data.crme_IdentityTheft == null ? "" : data.crme_IdentityTheft;
    row.setAttribute("crme_IdentityTheft", identityTheft);

    var phoneNumber = data.crme_PrimaryPhone == null ? "" : data.crme_PrimaryPhone;
    row.setAttribute("crme_PrimaryPhone", phoneNumber);

    var recordSource = data.crme_RecordSource == null ? "" : data.crme_RecordSource;
    row.setAttribute("crme_RecordSource", recordSource);

    var ssn = data.crme_SSN == null ? "" : data.crme_SSN;
    row.setAttribute("crme_SSN", ssn);

    var address = data.crme_FullAddress == null ? "" : data.crme_FullAddress;
    row.setAttribute("crme_FullAddress", serializeAddress(data));

    var fullName = data.crme_FullName == null ? "" : data.crme_FullName;
    row.setAttribute("crme_FullName", serializeName(data));

    row.setAttribute("crme_PatientMviIdentifier", data.crme_PatientMviIdentifier);

    if (data.crme_ClassCode != null)
        row.setAttribute("crme_ClassCode", data.crme_ClassCode);
    else
        row.setAttribute("crme_ClassCode", '');

    if (data.crme_ReturnMessage != null)
        row.setAttribute("crme_ReturnMessage", data.crme_ReturnMessage);
    else
        row.setAttribute("crme_ReturnMessage", '');

    var crmValues = [fullName, alias, gender, dateOfBirth, ssn, edipi, address, phoneNumber, deceasedDate, identityTheft, recordSource];
    return crmValues;
}

//Search Methods
function searchForPatient() {
    //Determine which of the Search Methods were selected
    var searchMethod = document.getElementById("SearchMethodDropdown").value;
    var filter = "";

    if (validateSearch(searchMethod) == true) {
        showExecutingSearch();
        if (searchMethod == "traits") {
            var DOB = $("#DateofBirthDateInput").val();
            var cleanDOB = new Date(DOB);
            var stringMM = cleanDOB.getMonth() + 1;
            var stringDD = cleanDOB.getDate();
            var stringDOB = "" + cleanDOB.getFullYear() + formatDatePart(stringMM.toString()) + formatDatePart(stringDD.toString());

            //Required parameters
            filter = "$select=*&$filter=";
            filter += buildQueryFilter("crme_FirstName", $("#FirstNameTextBox").val(), false);
            filter += buildQueryFilter("crme_LastName", $("#LastNameTextBox").val(), true);
            filter += buildQueryFilter("crme_SSN", $("#SocialSecurityTextBox").val(), true);
            filter += buildQueryFilter("crme_SearchType", 'SearchByFilter', true);
            filter += " and crme_IsAttended eq true";

            //Optional parameters
            filter += $("#MiddleNameTextBox").val() != "" ? buildQueryFilter("crme_MiddleName", $("#MiddleNameTextBox").val(), true) : "";
            filter += document.getElementById("SuffixDropdown").value != "" ? buildQueryFilter("crme_namesuffix", document.getElementById("SuffixDropdown").value, true) : "";
            filter += stringDOB != "" ? " and crme_DOBString eq '" + stringDOB + "'" : "";
            filter += $("#PhoneNoTextBox").val() != "" ? buildQueryFilter("crme_PrimaryPhone", $("#PhoneNoTextBox").val(), true) : "";
        }
        else {
            //Required parameters
            filter = "$select=*&$filter=";
            filter += buildQueryFilter("crme_EDIPI", $("#EdipiTextBox").val(), false);
            filter += buildQueryFilter("crme_ClassCode", 'MIL', true);
            filter += buildQueryFilter("crme_SearchType", 'SearchByIdentifier', true);
            filter += " and crme_IsAttended eq false";
        }
    }
    else
        showValidationFailed();

    if (filter != "") {
        try {
            SDK.REST.retrieveMultipleRecords("crme_person", filter, searchSucessCallback, searchErrorCallback, enableButtons);
        }
        catch (e) {
            searchErrorCallback(e);
        }
    }
}

//Add to query filter - single quote/apostrophe requires custom encoding here in JS and then decoding in the Plugin
function buildQueryFilter(field, value, and) {
    if (and)
        return " and " + field + " eq '" + encodeURIComponent(value).replace("'", "%APOS") + "'";
    else
        return field + " eq '" + encodeURIComponent(value).replace("'", "%APOS") + "'";
}

//Format a Pipe Delimited Full Address from the individual address fields
function serializeAddress(data) {
    if (data == null)
        return "";

    var addressLine = (data.crme_Address1 != null && data.crme_Address1 != "") ? data.crme_Address1 : "";
    var cityName = (data.crme_City != null && data.crme_City != "") ? data.crme_City : "";
    var stateName = (data.crme_StateProvinceId != null && data.crme_StateProvinceId.Name != null) ? data.crme_StateProvinceId.Name : "";
    var zipName = (data.crme_ZIPPostalCodeId != null && data.crme_ZIPPostalCodeId.Name != null) ? data.crme_ZIPPostalCodeId.Name : "";
    var countryName = (data.crme_countryId != null && data.crme_countryId.Name != null) ? data.crme_countryId.Name : "";

    return addressLine + "|" + cityName + "|" + stateName + "|" + zipName + "|" + countryName;
}

//Create a Pipe Delimited Full Name from the individual name fields
function serializeName(data) {
    if (data == null)
        return "";

    var lastName = (data.crme_LastName != null && data.crme_LastName != "") ?  data.crme_LastName : "";
    var firstName = (data.crme_FirstName != null && data.crme_FirstName != "") ? data.crme_FirstName : "";
    var middleName = (data.crme_MiddleName != null && data.crme_MiddleName != "") ? data.crme_MiddleName : "";
    var suffix = (data.crme_Suffix != null && data.crme_Suffix != "")  ? data.crme_Suffix : "";

    return lastName + "|" + firstName + "|" + middleName + "|" + suffix + "|"; //Removed prefix
}

//Create a Full Name from the individual name fields
function formatName(data) {
    if (data.crme_FullName != null) {
        return data.crme_FullName;
    }

    var name = "";
    name = data.crme_LastName != null ? data.crme_LastName : "";
    name += data.crme_Suffix != null ? " " + data.crme_Suffix : "";
    name += ", ";
    name += data.crme_FirstName != null ? data.crme_FirstName : "";
    name += data.crme_MiddleName != null ? " " + data.crme_MiddleName : "";
    name = name.trim();
    name = name == "," ? "" : name;

    return name;
}

//Format a Full Address from the individual address fields
function formatAddress(data) {
    if (data.crme_FullAddress != null) {
        return data.crme_FullAddress;
    }

    var street = data.crme_Address1 != null ? data.crme_Address1 : "";
    var city = data.crme_City != null ? data.crme_City : "";
    var state = data.crme_StateProvinceId != null ? data.crme_StateProvinceId : "";
    var zip = data.crme_ZIPPostalCodeId != null ? data.crme_ZIPPostalCodeId : "";

    return street + " " + city + " " + state + " " + zip;
}

//Format a one digit month or day into a two digit part
function formatDatePart(datepart) {
    return datepart.length == 1 ? "0" + datepart : datepart;
}

//Disable two buttons
function disableButtons() {
    $("#SearchButton").attr('disabled', true);
    $("#ClearButton").attr('disabled', true);
}

//Enable two buttons
function enableButtons() {
    $("#SearchButton").attr('disabled', false);
    $("#ClearButton").attr('disabled', false);
}

//Evaluate MVI Message
function evaluateMviMessage(data) {
    if (data == null) {
        $("#msgBoxSearchResultError").show();
        $("#errorDetails").text("");
        message = "An unexpected error occurred. Please try your search again.";
        $("#errorDetails").append(message);
        return false;
    }

    var message = data.crme_MviMessage;

    if (message == null)
        return true;

    //check the returned message for "no match" indicators
    var noMatchMessage = "No results were returned from MVI matching the search criteria provided. Please refine your search and try again.";
    var toManyMatches = "The query returned more than the allowable number of matches. Please refine your search and try again.";

    if (message.indexOf("[NF]") >= 0) {
        $("#warningDetails").text("");
        $("#warningDetails").append(noMatchMessage);
        $("#msgBoxNoDataReturned").show();
        return false;
    }

    if (message.indexOf("[QE]") >= 0) {
        $("#warningDetails").text("");
        $("#warningDetails").append(toManyMatches);
        $("#msgBoxNoDataReturned").show();
        return false;
    }

    //check for an error - display error dialog
    if (message.indexOf("[ER]") >= 0) {
        $("#msgBoxSearchResultError").show();
        $("#errorDetails").text("");
        $("#errorDetails").append(message.replace("[ER]", ""));
        return false;
    }

    return true;
}

//Show Executing Search
function showExecutingSearch() {
    hideAll();
    disableButtons();
    $("#msgBoxWorking").show();
    $("#msgBoxWorking").focus();
}

//Show Validation Failed
function showValidationFailed() {
    hideAll();
    enableButtons();
    $("#msgBoxFailedValidation").show();
    $("#msgBoxFailedValidation").focus();
}

//Show Error Details
function searchErrorCallback(error) {
    hideAll();
    enableButtons();
    $("#msgBoxSearchResultError").show();
    $("#errorDetails").text("");
    $("#errorDetails").append(error.message);
    $("#errorDetails").focus();
}

//Determine which of the Search Methods were selected
function searchChange() {
    resetForm();
    
    var searchMethod = document.getElementById("SearchMethodDropdown").value;
    var searchBtnText = "Search by Person Traits";

    if (searchMethod == "traits") {
        $("#searchByTraits").show();
        $("#searchByIdentifier").hide();
    }
    else {
        searchBtnText = "Search by EDIPI";
        $("#searchByTraits").hide();
        $("#searchByIdentifier").show();
    }

    //Modify search button
    $("#SearchButton")[0].innerHTML = searchBtnText;
    $("#SearchButton")[0].innerText = searchBtnText;
    $("#SearchButton")[0].title = searchBtnText;
}

//Hide all Message Divs
function hideAll() {
    $("#msgBoxWorking").hide();
    $("#msgBoxFailedValidation").hide();
    $("#msgBoxSearchResultError").hide();
    $("#msgBoxNoDataReturned").hide();
    $("#searchResultsGrid").hide();
}

//Clear Fields, Hide Divs
function resetForm() {
    //Clear fields
    $("#EdipiTextBox").val("");
    $("#FirstNameTextBox").val("");
    $("#MiddleNameTextBox").val("");
    $("#LastNameTextBox").val("");
    $("#DateofBirthDateInput").val("");
    $("#PhoneNoTextBox").val("");
    $("#SocialSecurityTextBox").val("");
    document.getElementById("SuffixDropdown").value = "";

    //clear out possible notifications
    $("#FirstNameNotification").html("");
    $("#LastNameNotification").html("");
    $("#SSNotification").html("");
    $("#DOBNotification").html("");
    $("#EDIPINotification").html("");

    //Hide grids
    hideAll()
    enableButtons();

    //Set focus to the Search Method
    document.getElementById("SearchMethodDropdown").focus();
}

//Clear out default value to ""
function clearField(obj) {
    if (obj.defaultValue == obj.value)
        obj.value = "";
}

//Required Field Validation
function CheckRequiredField(fieldName, text, displayArea) {
    //Check the field for text, if empty, pop open a new image with alt text.
    var fieldValue = $(fieldName).val();
    var msg = "";
    $("#" + displayArea)[0].setAttribute("aria-haspopup", false);

    if (fieldValue == "")
        msg = "Please enter the " + text + ", it is required.";
    else if (text == "Social Security Number") {
        if (fieldValue != "" || fieldValue != " 9 digits, no dashes") {
            var checkNumber = validateNumeric(fieldValue.trim(), "Social Security Number");
            if (checkNumber != "")
                msg = checkNumber;
        }
    }
    else if (text == "EDIPI") {
        var checkNumber = validateNumeric(fieldValue.trim(), "EDIPI");
        if (checkNumber != "")
            msg = checkNumber;
    }
    if (msg != "")
        $("#" + displayArea)[0].setAttribute("aria-haspopup", true);

    msg = '<font color="red">' + msg + '</font>';
    $("#" + displayArea).html(msg); 
}

//Format Date of Birth
function FormatDOB(location) {
    var rawDOB = $(DateofBirthDateInput).val();
    var cleanDOB = rawDOB.replace(/\D/g, '');
    var cleanDOBwithSlashes = rawDOB.replace(/[^0-9/]/g, '');
    var msg = "";
    var formattedDOB = cleanDOBwithSlashes;

    if (rawDOB.length != 0) {
        if (cleanDOB.length == 8 && cleanDOBwithSlashes.length == 8 && rawDOB.length == 8) {
            msg = '<font color="blue">' + "Attempted to format DOB from MMDDYYYY to MM/DD/YYYY." + '</font>';
            formattedDOB = rawDOB.substring(0, 2) + "/" + rawDOB.substring(2, 4) + "/" + rawDOB.substring(4, 8);
        }
        else if ((rawDOB.length != 10 && cleanDOBwithSlashes.length != 10) || (cleanDOB.length != 8)) {
            msg = "Date of Birth must be formatted MM/DD/YYYY.";
            formattedDOB = cleanDOBwithSlashes;
        }

        if (formattedDOB.length == 10) {
            var validateDate = new Date(formattedDOB);
            var currentDate = new Date();
            var earlyDate = new Date("01/01/1850");
            if (validateDate == "Invalid Date")
                msg = "Invalid Date: Cannot convert into real date.";
            else if (earlyDate > validateDate)
                msg = "Invalid Date: Date entered is too far in the past.";
            else if (validateDate > currentDate)
                msg = "Invalid Date: Date entered is too far in the future.";
        }
    }

    if (location == "field") {
        msg = '<font color="red">' + msg + '</font>';       
        $("#DateofBirthDateInput").val(formattedDOB);
        $("#DOBNotification").html(msg);
    }
    else
        return msg;

}

//Validate Fields before actual search
function validateSearch(searchMethod) {
    //Remove existing items
    $("#validationErrors").find("ul").remove();
    var html = "";

    if (searchMethod == "traits") {
        var ssn = $("#SocialSecurityTextBox").val();

        html += ($("#FirstNameTextBox").val() == "") ? "<li>The First Name is missing.</li>" : "";
        html += ($("#LastNameTextBox").val() == "") ? "<li>The Last Name is missing.</li>" : "";

        if (ssn == "" || ssn == " 9 digits, no dashes") {
            html += "<li>The Social Security Number is missing.</li>";
        }
        else {
            var checkNumber = validateNumeric(ssn.trim(), "Social Security Number");
            html += (checkNumber != "") ? "li>" + checkNumber + "</li>" : "";
        }

        html += (!$("#DateofBirthDateInput").val() && $("#PhoneNoTextBox").val() == "") ? "<li>Must include either the Date of Birth or a Phone Number.</li>" : "";

        if ($("#DateofBirthDateInput").val()) {
            var DOBvalidation = (FormatDOB("button"));
            if (DOBvalidation != "")
                html += "<li>" + DOBvalidation + "</li>";
        }
    }
    //EDIPI
    else {
        var edipi = $("#EdipiTextBox").val();

        html += (edipi == "") ? "<li>The EDIPI is missing.</li>" : "";
        if (edipi != "") {
            var checkNumber = validateNumeric(edipi.trim(), "EDIPI");
            html += (checkNumber != "") ? "<li>" + checkNumber + "</li>" : "";
        }
    }
    if (html != "") {
        html = "<ul id='errorList'>" + html + "</ul>";
        $("#validationErrors").append(html);
        return false;
    }
    else
        return true;
}

//Check if Number and if correct length
function validateNumeric(value, type) {
    var cleanNo = value.replace(/\D/g, '');
    var len = 9; //Assume Social Security Number

    if (type == "EDIPI")
        len = 10;

    if (value.length != cleanNo.length)
        return "The " + type + " cannot contain non numbers.";
    else if (cleanNo.length != len)
        return "The " + type + " must be " + len + " numbers in length.";

    return "";
}